package com.linkoog.devtools.dubbo.action;


import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReferenceExpression;
import com.linkoog.devtools.dubbo.raw_index.DubboMethod;
import com.linkoog.devtools.dubbo.raw_index.DubboMethodRawFileIndex;
import com.linkoog.devtools.dubbo.toolwindow.DubboToolWindowManager;
import org.jetbrains.annotations.NotNull;

import static com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR;
import static com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT;

/**
 *
 */
public class DubboTestEditerPopupAction extends AnAction {

    /**
     */
    @Override
    public void actionPerformed(AnActionEvent e) {
        Project project = e.getData(PROJECT);
        if (project == null) return;

        PsiMethod psiMethod = getPsiMethod(e.getData(CommonDataKeys.PSI_ELEMENT));
        if (psiMethod == null) return;

        PsiClass psiClass = psiMethod.getContainingClass();
        if (psiClass == null) return;

        DubboMethod dubboMethod =  DubboMethodRawFileIndex.getInstance(project).getCache(psiMethod);
        if (dubboMethod == null) return;

        DubboToolWindowManager.getInstance(project).show(dubboMethod);
    }

    @Override
    public void update(AnActionEvent e) {
        Project project = e.getData(PROJECT);
        PsiElement element = e.getData(CommonDataKeys.PSI_ELEMENT);
        PsiMethod psiMethod = getPsiMethod(element);
        e.getPresentation().setVisible(project != null  && psiMethod != null);
    }

    @Override
    public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.BGT;
    }


    /**
     * 解析当前光标选中的元素, 返回 PsiMethod.
     *
     * @param element element
     * @since 1.1.0
     */
    public static PsiMethod getPsiMethod(PsiElement element) {
        PsiMethod method = null;
        if (element instanceof PsiMethod) {
            method = (PsiMethod) element;
        } else if (element instanceof PsiIdentifier) {
            // 如果标识符是方法
            if (element.getParent() instanceof PsiMethod) {
                method = (PsiMethod) element.getParent();
            } else if (element.getParent() instanceof PsiReferenceExpression) {
                // 如果标识符是方法引用
                PsiElement resolve = ((PsiReferenceExpression) element.getParent()).resolve();
                if (resolve instanceof PsiMethod) {
                    method = (PsiMethod) resolve;
                }
            }
        }
        return method;
    }

}
